/*
 * 返回友好格式的日期字符串
 *
 * @param dateStr 日期字符串
 * @return 格式化后的日期字符串
 * */
import {ElMessage, ElMessageBox} from "element-plus";
import router from "@/router";

export function dateFormat(dateStr) {

    // 用于将六大元素处理为两位数格式（年除外）
    function toDouble(e) {
        return e < 10 ? '0' + e : e;
    }

    // 将日期字符串转为日期格式
    let date = new Date(dateStr);

    // 获取日期中的六大元素: 年，月，日，时，分，秒
    let yy = toDouble(date.getFullYear());
    let mm = toDouble(date.getMonth() + 1);
    let dd = toDouble(date.getDate());
    let hh = toDouble(date.getHours());
    let mi = toDouble(date.getMinutes());
    let ss = toDouble(date.getSeconds());

    // 返回美化后的日期字符串
    return `${yy}年${mm}月${dd}日 ${hh}:${mi}:${ss}`;
}

/*
 * 根据性别代码，返回对应的性别字符
 *
 * @param genderCode 性别代码
 * @return 对应的性别字符，0女孩，1男孩，2保密
 * */
export function genderFormat(genderCode) {
    if (genderCode === '0' || genderCode === 0) return '女';
    if (genderCode === '1' || genderCode === 1) return '男';
    if (genderCode === '2' || genderCode === 2) return '保密';
    return '性别代码异常';
}

/*
 * 获取服务器响应中的数据
 *
 * @param res axios响应对象
 * @return 响应成功时返回data数据或true，响应失败时返回false
 * */
export function getResponseData(res) {

    // 若存在2层data，则直接拆除第1层data
    res = res.data.data !== undefined ? res.data : res;

    // 请求成功时返回数据或true
    if (res.code === 200) {
        return res.data !== null ? res.data : true;
    }else if (res.code === 1001){
        ElMessage.warning('Token过期，请重新登录！');
        setTimeout(() => router.push('/'), 1000);
        return false;
    }
    // 请求失败时返回false
    else {
        ElMessage.warning('请求失败: ' + res.data);
        return false;
    }
}

/*
 * 封装分页查询数据的异步过程
 *
 * <ul>
 *  <li> api: API请求函数名（不带小括号），必传 </li>
 *  <li> params: API请求参数，可选 </li>
 *  <li> records: 分页结果中的数据记录，必传 </li>
 *  <li> pageInfo: 分页结果中的元信息，包括当前第几页，每页多少条以及一共多少条，必传 </li>
 * </ul>
 */
export async function myPage(config) {
    const api = config['api'];
    const params = config['params'];
    const records = config['records'];
    const pageInfo = config['pageInfo'];

    // 空值保护
    if (!api || !records || !pageInfo) return;

    let res = await api(params);
    let data = getResponseData(res);
    if (data) {
        records.value = data['list'] || data['records'];
        pageInfo['currentPage'] = data['pageNum'] || data['pageNumber'];
        pageInfo['pageSize'] = data['pageSize'];
        pageInfo['total'] = data['total'] || data['totalRow'];
    }
}

/*
 * 封装使用表单添加数据的异步过程
 *
 * <ul>
 *  <li> form: 表单对象，必须是reactive变量，必传 </li>
 *  <li> api: API请求函数名（不带小括号），必传 </li>
 *  <li> params: API请求参数，可选 </li>
 *  <li> fn: 回调函数名（不带小括号），即当请求成功后，调用的函数，可选 </li>
 *  <li> needTip: 是否需要成功提示，默认是，可选 </li>
 *  <li> successTip: 操作成功后的提示文字，可选 </li>
 *  <li> needResetForm: 是否需要重置表单，默认是，可选 </li>
 * </ul>
 * */
export async function myInsert(config) {
    const form = config['form'];
    const api = config['api'];
    const params = config['params'];
    const fn = config['fn'];
    const needTip = config['needTip'] || true;
    const successTip = config['successTip'] || `数据添加成功！`;
    const needResetForm = config['needResetForm'] || true;

    // 空值保护
    if (!form || !api) return;

    // 验证表单
    form.value.validate(async (valid) => {
        // 只有全部校验规则都通过，valid参数才为true
        if (valid) {
            // 发送请求
            let data = getResponseData(await api(params));
            if (data) {
                // 成功提示
                if (needTip) ElMessage.success(successTip);
                // 存在回调函数时，异步调用回调函数
                if (fn) await fn();
            }
/*            // 重置表单
            if (needResetForm) form.value.resetFields();*/
        }
    });
}

/*
 * 封装使用表单修改数据的异步过程
 *
 * <ul>
 *  <li> form: 表单对象，必须是reactive变量，必传 </li>
 *  <li> api: API请求函数名（不带小括号），必传 </li>
 *  <li> params: API请求参数，可选 </li>
 *  <li> fn: 回调函数名（不带小括号），即当请求成功后，调用的函数，可选 </li>
 *  <li> needTip: 是否需要成功提示，默认是，可选 </li>
 *  <li> successTip: 操作成功后的提示文字，可选 </li>
 *  <li> needResetForm: 是否需要重置表单，默认是，可选 </li>
 * </ul>
 */
export async function myUpdate(config) {
    config['successTip'] = config['successTip'] || `数据修改成功！`;
    await myInsert(config);
}

/*
 * 封装按主键删除单条数据的异步过程
 *
 * <ul>
 *  <li> id: 主键，必传 </li>
 *  <li> api: API请求函数名（不带小括号），必传 </li>
 *  <li> fn: 回调函数名（不带小括号），即当请求成功后，调用的函数，可选 </li>
 *  <li> needTip: 是否需要成功提示，默认是，可选 </li>
 *  <li> confirmTip: 危险操作保护提示文字，可选 </li>
 *  <li> successTip: 操作成功后的提示文字，可选 </li>
 * </ul>
 */
export async function myRemove(config) {

    const id = config['id'];
    const api = config['api'];
    const fn = config['fn'];
    const needTip = config['needTip'] || true;
    const confirmTip = config['confirmTip'] || `即将删除1条数据，确认吗？`;
    const successTip = config['successTip'] || `数据删除成功！`;

    // 空值保护
    if (id === null || !api) return;

    // 危险操作保护
    if (!await elConfirm(confirmTip)) return;

    // 发送请求
    let res = await api(id);

    // 解析响应中的数据
    let data = getResponseData(res);
    if (data) {

        // 成功提示
        if (needTip) ElMessage.success(successTip);

        // 异步调用回调函数
        if (fn) await fn();
    }
}

/*
 * 封装按主键数组批量删除多条数据的异步过程
 *
 * <ul>
 *  <li> ids: 主键数组，必传 </li>
 *  <li> api: API请求函数名（不带小括号），必传 </li>
 *  <li> fn: 回调函数名（不带小括号），即当请求成功后，调用的函数，可选 </li>
 *  <li> needTip: 是否需要成功提示，默认是，可选 </li>
 *  <li> confirmTip: 危险操作保护提示文字，可选 </li>
 *  <li> successTip: 操作成功后的提示文字，可选 </li>
 * </ul>
 */
export async function myRemoveBatch(config) {

    const ids = config['ids'];
    const api = config['api'];
    const fn = config['fn'];
    const needTip = config['needTip'] || true;
    const confirmTip = config['confirmTip'] || `即将删除 ${ids.length} 条数据，确认吗？`;
    const successTip = config['successTip'] || `成功删除 ${ids.length} 条数据！`;

    // 主键数组空值保护
    if (!ids || ids.length <= 0) {
        ElMessage.warning('至少选择1项！');
        return;
    }

    // 危险操作保护
    if (!await elConfirm(confirmTip)) return;

    // 发送请求
    let res = await api(ids.join(','));

    // 解析响应中的数据
    let data = getResponseData(res);
    if (data) {

        // 成功提示
        if (needTip) ElMessage.success(successTip);

        // 异步调用回调函数
        if (fn) await fn();
    }
}

/*
 * 封装EL确认弹窗
 *
 * @param message 弹窗内容
 * @param type 弹窗类型，默认 'warning'
 * @param title 弹窗标题，默认 '注意'
 * @param draggable 是否可拖动弹窗，默认是
 * @param confirmButtonLabel 确定按钮文字，默认 '确认，我很坚定'
 * @param cancelButtonLabel 取消按钮文字，默认 '取消，我后悔了'
 * @return true确认，false取消
 */
export function elConfirm(message, type = 'warning', title = '注意', draggable = true,
                          confirmButtonLabel = '确认，我很坚定',
                          cancelButtonLabel = '取消，我后悔了') {

    return ElMessageBox.confirm(message, title, {
        confirmButtonText: confirmButtonLabel,
        cancelButtonText: cancelButtonLabel,
        type: type,
        draggable: draggable
    }).then(() => true).catch(() => false);
}
